﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ServiceStack.Redis;
using ServiceManager.Utils;
namespace QuotationService.RealtimeQuotation
{
    /// <summary>
    /// 基本资料通道
    /// </summary>
    [DebuggerNonUserCode]
    internal static class BasicInfoChannel
    {
        /// <summary>
        /// 更新基本资料
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static bool Update(QuotationSource source, string code, byte[] data)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            if (data == null || data.Length == 0)
                throw new ArgumentNullException("data");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Update BasicInfo", 1))
            {
                //更新
                return publisher.Update(source.ToFormatString() + ":" + QuotationDataType.BasicInfo.ToFormatString(), code, data);
            }
        }

        /// <summary>
        /// 发布基本资料
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static bool Publish(QuotationSource source, string code, byte[] data)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            if (data == null || data.Length == 0)
                throw new ArgumentNullException("data");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Publish BasicInfo", 1))
            {
                //更新并发布
                return publisher.Publish(source.ToFormatString() + ":" + QuotationDataType.BasicInfo.ToFormatString() + ":" + code.PadLeft(10, '#'), data);
            }
        }

        /// <summary>
        /// 发布基本资料
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="authCode"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static bool Publish(QuotationSource source, string code, string authCode, byte[] data)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            if (data == null || data.Length == 0)
                throw new ArgumentNullException("data");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Publish BasicInfo", 1))
            {
                //更新并发布
                return publisher.Publish(source.ToFormatString() + ":" + QuotationDataType.BasicInfo.ToFormatString() + ":" +
                                                    code.PadLeft(10, '#') + ":" + authCode.PadLeft(20, '#'), data);
            }
        }

        /// <summary>
        /// 获取所有商品的代码
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<string> GetAllCodes(QuotationSource source)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            using (var conn = QuotationSubscribeServiceContainer.GetNeedDisposedConnection(source))
            {
                if (conn == null)
                    return null;

                using (new ProcessTime("Get All Codes", 1))
                {
                    var retValues = (conn as RedisClient).HKeys(source.ToFormatString() + ":" + QuotationDataType.BasicInfo.ToFormatString());
                    if (retValues == null)
                        return null;

                    return retValues.Select(x => x.FromUtf8Bytes()).ToList();
                }
            }
        }

        /// <summary>
        /// 获取所有商品基本信息
        /// </summary>
        /// <param name="source"></param>
        /// <returns></returns>
        public static List<byte[]> GetAll(QuotationSource source)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            using (var conn = QuotationSubscribeServiceContainer.GetNeedDisposedConnection(source))
            {
                if (conn == null)
                    return null;

                using (new ProcessTime("Get All BasicInfos", 1))
                {
                    var retValues = (conn as RedisClient).HVals(source.ToFormatString() + ":" + QuotationDataType.BasicInfo.ToFormatString());
                    if (retValues == null)
                        return null;

                    return retValues.ToList();
                }
            }
        }

        /// <summary>
        /// 获取单只商品基本信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static byte[] Get(QuotationSource source, string code)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            using (var conn = QuotationSubscribeServiceContainer.GetNeedDisposedConnection(source))
            {
                if (conn == null)
                    return null;

                using (new ProcessTime("Get Single BasicInfo", 1))
                {
                    return (conn as RedisClient).HGet(source.ToFormatString() + ":" + QuotationDataType.BasicInfo.ToFormatString(), code.ToUtf8Bytes());
                }
            }
        }

        /// <summary>
        /// 删除单只商品的基本信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static bool Clear(QuotationSource source, string code)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                throw new ArgumentNullException("code");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Clear Single BasicInfo", 1))
            {
                return publisher.Delete(source.ToFormatString() + ":" + QuotationDataType.BasicInfo.ToFormatString(), code);
            }
        }


        /// <summary>
        /// 删除全部商品的基本信息
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <returns></returns>
        public static bool Clear(QuotationSource source)
        {
            if (source == null)
                throw new ArgumentNullException("source");

            var publisher = QuotationPublishServiceContainer.GetPublishService(source);
            if (publisher == null)
                return false;

            using (new ProcessTime("Clear All BasicInfo", 1))
            {
                return publisher.Delete(string.Format("{0}:{1}", source.ToFormatString(), QuotationDataType.BasicInfo.ToFormatString()));
            }
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="source"></param>
        /// <param name="code"></param>
        /// <param name="authCode"></param>
        /// <returns></returns>
        public static string ToSubscribeChannel(QuotationSource source, string code = "", string authCode = "")
        {
            if (source == null)
                throw new ArgumentNullException("source");

            if (string.IsNullOrEmpty(code))
                code = "??????????";

            if (!string.IsNullOrEmpty(authCode))
                authCode = ":" + authCode.PadLeft(20, '#');
            else
                authCode = "*";

            return source.ToFormatString() + ":" + QuotationDataType.BasicInfo.ToFormatString() + ":" + code.PadLeft(10, '#') + authCode;
        }
    }

}
